package com.ijtunes.filetypes;

import com.ijtunes.iTunesCOM;
import com.ijtunes.utils.Logger;
import com.ijtunes.utils.Properties;
import com.ijtunes.utils.Property;

import com.itunes.IITFileOrCDTrack;
import com.itunes.ITVideoKind;

import com4j.ComException;

/**
 * iTunes-related implementation of a track.
 * @author Michael Sena
 * @version 1.0
 * @date 01/07/2010
 */
public class ITunesTrack extends Track {
    /** Number of times the item has been played in iTunes. */
    private int playedCount = -1;
    /** Number of plays recorded on Last.fm. */
    private int onlinePlayedCount = -1;
    /** Holds the iTunes COM object for the track. */
    private IITFileOrCDTrack track = null;

    /**
     * Default constructor.
     * @param iTunesTrack iTunes COM Object
     */
    public ITunesTrack(final IITFileOrCDTrack iTunesTrack) {
        track = iTunesTrack;
        name = track.name();
        artist = track.artist();
        location = track.location();
        // TODO: Better track exists detection.
        exists = (location != null);
        // TODO: Determining supported iTunes tracks might not be reliable.
        supported = (track.videoKind() == ITVideoKind.ITVideoKindNone);
    }

    /**
     * Deletes the track from the iTunes library.
     */
    public final void delete() {
        track.delete();
    }

    /**
     * Album the track appears on.
     * @return String version of the album name.
     */
    @Override
    public final String getAlbum() {
        if (album == null) {
            try {
                album = track.album();
            } catch (ComException ce) {
                Logger.log(this,
                    "Error getting album for track: " + track.name(),
                    ce);
            }
            if (album == null) {
                album = Track.DEFAULT_BLANK;
            }
        }
        return album;
    }

    /**
     * Genre of the track.
     * @return String version of the genre.
     */
    @Override
    public final String getGenre() {
        if (genre == null) {
            genre = track.genre();
            if (genre == null) {
                genre = Track.DEFAULT_BLANK;
            }
        }
        return genre;
    }

    /**
     * Artist of the whole album (different).
     * @return String version of the album artist
     */
    @Override
    public final String getAlbumArtist() {
        if (albumArtist == null) {
            albumArtist = track.albumArtist();
            if (albumArtist == null) {
                albumArtist = Track.DEFAULT_BLANK;
            }
        }
        return albumArtist;
    }

    /**
     * Retrieves how many times the track has been played in iTunes.
     * @return Integer representation of this amount
     */
    public final int getPlayedCount() {
        if (playedCount < 0) {
            playedCount = track.playedCount();
        }
        return playedCount;
    }

    /**
     * Sets the genre of the track.
     * @param trackGenre Genre name to store
     */
    @Override
    public final void setGenre(final String trackGenre) {
        track.genre(genre);
    }

    /**
     * Update the number of times a track has been played in the iTunes library.
     * @param trackPlayedCount Integer value to change it to
     */
    public final void setPlayedCount(final int trackPlayedCount) {
        track.playedCount(trackPlayedCount);
    }

    /**
     * Number of times a track has been played on Last.fm.
     * @return Integer version of this amount
     */
    public final int getOnlinePlayedCount() {
        try {
            if (onlinePlayedCount == -1) {
                onlinePlayedCount = Integer.parseInt(
                    net.roarsoftware.lastfm.Track.getInfo(
                    artist,
                    name,
                    Properties.get(Property.USERNAME),
                    Properties.get(Property.APIKEY)).getUserPlayCount());
            }
        } catch (NumberFormatException nfe) {
            onlinePlayedCount = 0;
        } catch (NullPointerException npe) {
            onlinePlayedCount = 0;
        }
        return onlinePlayedCount;
    }

    /**
     * Track number on the album.
     * @return Integer version of the track number.
     */
    @Override
    public final int getTrackNum() {
        if (trackNum == -1) {
            trackNum = track.trackNumber();
        }
        return trackNum;
    }
    
    /**
     * Whether the track is currently playing in iTunes or not.
     * @return Whether it is playing
     */
    public final boolean isPlaying() {
        return iTunesCOM.getInstance().currentTrack().equals(track);
    }
    
    /**
     * Updates the location of the file for the iTunes track entry.
     * @param newLocation New location to use
     */
    public final void setLocation(final String newLocation) {
        track.location(newLocation);
        location = newLocation;
    }
}
